package com.engine4cloud.tdf.supervision.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.engine4cloud.tdf.common.core.exception.ValidateCodeException;
import com.engine4cloud.tdf.common.data.web.query.Pages;
import com.engine4cloud.tdf.common.data.web.query.Queries;
import com.engine4cloud.tdf.common.data.web.response.PageInfo;
import com.engine4cloud.tdf.common.data.web.response.Params;
import com.engine4cloud.tdf.supervision.convert.JzdxFamilySocietyConvert;
import com.engine4cloud.tdf.supervision.dto.create.JzdxFamilySocietyCreateDTO;
import com.engine4cloud.tdf.supervision.dto.query.JzdxFamilySocietyQueryDTO;
import com.engine4cloud.tdf.supervision.dto.result.JzdxFamilySocietyResultDTO;
import com.engine4cloud.tdf.supervision.dto.result.JzdxResultDTO;
import com.engine4cloud.tdf.supervision.dto.update.JzdxFamilySocietyUpdateDTO;
import com.engine4cloud.tdf.supervision.entity.JzdxFamilySocietyEntity;
import com.engine4cloud.tdf.supervision.mapper.JzdxFamilySocietyMapper;
import com.engine4cloud.tdf.supervision.service.JzdxFamilySocietyService;
import com.engine4cloud.tdf.supervision.service.JzdxService;
import jakarta.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 矫正对象家庭社会关系信息表
 *
 * @author wenjie
 * @date 2024-04-01 14:22:32
 */
@Service
public class JzdxFamilySocietyServiceImpl extends ServiceImpl<JzdxFamilySocietyMapper, JzdxFamilySocietyEntity> implements JzdxFamilySocietyService {
    @Resource
    private JzdxService jzdxService;

    @Override
    public PageInfo<JzdxFamilySocietyResultDTO> pageList(Params pageable, JzdxFamilySocietyQueryDTO dto) {
        IPage<JzdxFamilySocietyResultDTO> page = this.baseMapper.pageList(Pages.page(pageable), dto);
        return Pages.convert(page);
    }

    @Override
    public List<JzdxFamilySocietyResultDTO> findList(JzdxFamilySocietyQueryDTO dto) {
        return list(wrapper(dto)).stream().map(JzdxFamilySocietyConvert.INSTANCE::convert).toList();
    }

    @Override
    public JzdxFamilySocietyResultDTO getById(Long id) {
        return JzdxFamilySocietyConvert.INSTANCE.convert(super.getById(id));
    }

    @Override
    public Boolean create(JzdxFamilySocietyCreateDTO dto) {
        JzdxResultDTO dx = Optional.ofNullable(jzdxService.getByCode(dto.getRybh()))
                .orElseThrow(() -> new ValidateCodeException("矫正对象数据不存在"));

        return super.save(JzdxFamilySocietyConvert.INSTANCE.create(dto, dx.getTenantId()));
    }

    @Override
    public Boolean update(JzdxFamilySocietyUpdateDTO dto) {
        JzdxFamilySocietyEntity old = Optional.ofNullable(super.getById(dto.getId()))
                .orElseThrow(() -> new ValidateCodeException("数据不存在"));
        return super.saveOrUpdate(JzdxFamilySocietyConvert.INSTANCE.update(dto));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createBatch(String code, List<JzdxFamilySocietyEntity> familySocietyEntityList) {
        JzdxResultDTO dx = Optional.ofNullable(jzdxService.getByCode(code))
                .orElseThrow(() -> new ValidateCodeException("矫正对象数据不存在"));

        if (CollectionUtils.isNotEmpty(familySocietyEntityList)) {
            familySocietyEntityList.forEach(each -> each.setRybh(code));
            super.saveBatch(familySocietyEntityList);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateBatch(String code, List<JzdxFamilySocietyEntity> familySocietyEntityList) {
        //查询已经存在的
        List<JzdxFamilySocietyResultDTO> existedList = this.findList(new JzdxFamilySocietyQueryDTO(code));

        //需要保存的
        List<JzdxFamilySocietyEntity> preSaveList = this.preSaveList(familySocietyEntityList);
        if (CollectionUtils.isNotEmpty(preSaveList)) {
            this.saveBatch(preSaveList);
        }

        //需要删除的
        List<Long> preDeleteList = this.preDeleteList(existedList, familySocietyEntityList);
        if (CollectionUtils.isNotEmpty(preDeleteList)) {
            this.removeBatchByIds(preDeleteList);
        }

        //需要更新的
        List<JzdxFamilySocietyEntity> preUpdateList = this.preUpdateList(existedList, familySocietyEntityList);
        if (CollectionUtils.isNotEmpty(preUpdateList)) {
            this.updateBatchById(preUpdateList);
        }

        return true;
    }

    @Override
    public List<JzdxFamilySocietyEntity> findByCode(String code) {
        LambdaQueryWrapper<JzdxFamilySocietyEntity> wrapper = Queries.lambda();
        Queries.accept(code, v -> wrapper.eq(JzdxFamilySocietyEntity::getRybh, v));
        return list(wrapper);
    }

    private LambdaQueryWrapper<JzdxFamilySocietyEntity> wrapper(JzdxFamilySocietyQueryDTO query) {
        LambdaQueryWrapper<JzdxFamilySocietyEntity> wrapper = Queries.lambda();
        Queries.accept(query.getId(), v -> wrapper.eq(JzdxFamilySocietyEntity::getId, v));
        Queries.accept(query.getRybh(), v -> wrapper.eq(JzdxFamilySocietyEntity::getRybh, v));
        return wrapper;
    }

    private List<JzdxFamilySocietyEntity> preSaveList(List<JzdxFamilySocietyEntity> entityList) {
        if (CollectionUtils.isEmpty(entityList)) {
            return Collections.emptyList();
        }

        return entityList.stream().filter(file -> Objects.isNull(file.getId())).toList();
    }

    private List<Long> preDeleteList(List<JzdxFamilySocietyResultDTO> existedList, List<JzdxFamilySocietyEntity> modelList) {
        if (CollectionUtils.isEmpty(existedList)) {
            return Collections.emptyList();
        }

        Map<Long, JzdxFamilySocietyEntity> modelMap = modelList.stream().filter(model -> Objects.nonNull(model.getId())).collect(Collectors.toMap(JzdxFamilySocietyEntity::getId, Function.identity(), (v1, v2) -> v1));
        return existedList.stream().map(JzdxFamilySocietyResultDTO::getId).filter(id -> !modelMap.containsKey(id)).toList();
    }

    private List<JzdxFamilySocietyEntity> preUpdateList(List<JzdxFamilySocietyResultDTO> existedList, List<JzdxFamilySocietyEntity> modelList) {
        if (CollectionUtils.isEmpty(existedList) || CollectionUtils.isEmpty(modelList)) {
            return Collections.emptyList();
        }

        List<JzdxFamilySocietyEntity> preUpdateList = new ArrayList<>();

        Map<Long, JzdxFamilySocietyResultDTO> existedMap = existedList.stream().collect(Collectors.toMap(JzdxFamilySocietyResultDTO::getId, v -> v));
        for (JzdxFamilySocietyEntity resume : modelList) {
            if (Objects.nonNull(resume.getId()) && existedMap.containsKey(resume.getId())) {
                preUpdateList.add(resume);
            }
        }

        return preUpdateList;
    }
}